// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com)

using System;
using System.Runtime.InteropServices;

namespace NPack
{
    [StructLayout(LayoutKind.Sequential)]
    public struct SingleComplex : IComparable<SingleComplex>, IComparable<Single>, IComparable,
                                  IEquatable<SingleComplex>, IEquatable<Single>
    {
        private readonly Single _real;
        private readonly Single _imaginary;

        public SingleComplex(Single real, Single imaginary)
        {
            _real = real;
            _imaginary = imaginary;
        }

        public override String ToString()
        {
            return String.Format("{0:N8} + {1:N8}i", _real, _imaginary);
        }

        public override Int32 GetHashCode()
        {
            return _real.GetHashCode() ^ _imaginary.GetHashCode();
        }

        public Single Real
        {
            get { return _real; }
        }

        public Single Imaginary
        {
            get { return _imaginary; }
        }

        public static SingleComplex operator -(SingleComplex value)
        {
            return new SingleComplex(-value._real, -value._imaginary);
        }

        public static SingleComplex operator +(SingleComplex lhs, SingleComplex rhs)
        {
            return new SingleComplex(lhs._real + rhs._real, lhs._imaginary + rhs._imaginary);
        }

        public static SingleComplex operator +(SingleComplex lhs, Single rhs)
        {
            return new SingleComplex(lhs._real + rhs, lhs._imaginary);
        }

        public static SingleComplex operator +(Single lhs, SingleComplex rhs)
        {
            return new SingleComplex(lhs + rhs._real, rhs._imaginary);
        }

        public static SingleComplex operator -(SingleComplex lhs, SingleComplex rhs)
        {
            return new SingleComplex(lhs._real - rhs._real, lhs._imaginary - rhs._imaginary);
        }

        public static SingleComplex operator -(Single lhs, SingleComplex rhs)
        {
            return new SingleComplex(lhs - rhs._real, rhs._imaginary);
        }

        public static SingleComplex operator -(SingleComplex lhs, Single rhs)
        {
            return new SingleComplex(lhs._real - rhs, lhs._imaginary);
        }

        public static SingleComplex operator *(SingleComplex lhs, SingleComplex rhs)
        {
            return new SingleComplex(lhs._real*rhs._real, lhs._imaginary*rhs._imaginary);
        }

        public static SingleComplex operator /(SingleComplex lhs, SingleComplex rhs)
        {
            return new SingleComplex(lhs._real/rhs._real, lhs._imaginary/rhs._imaginary);
        }

        public static implicit operator DoubleComplex(SingleComplex value)
        {
            return new SingleComplex(value._real, value._imaginary);
        }

        #region IComparable<SingleComplex> Members

        public Int32 CompareTo(SingleComplex other)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IComparable<Single> Members

        public Int32 CompareTo(Single other)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IEquatable<SingleComplex> Members

        public Boolean Equals(SingleComplex other)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IEquatable<Single> Members

        public Boolean Equals(Single other)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IComparable Members

        public Int32 CompareTo(Object obj)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}